package maple.thelittleredbook.interaction.service;

import lombok.extern.slf4j.Slf4j;
import maple.thelittleredbook.content.mapper.ContentMapper;
import maple.thelittleredbook.interaction.entity.Like;
import maple.thelittleredbook.interaction.mapper.CommentMapper;
import maple.thelittleredbook.interaction.mapper.LikeMapper;
import maple.thelittleredbook.interaction.mapper.UserBehaviorMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * 点赞服务
 * 负责点赞的同步操作（点赞记录增删、统计更新）
 */
@Slf4j
@Service
public class LikeService {

    private final LikeMapper likeMapper;
    private final UserBehaviorMapper userBehaviorMapper;
    private final AsyncUserBehaviorService asyncUserBehaviorService;
    private final ContentMapper contentMapper;
    private final CommentMapper commentMapper;

    @Autowired
    public LikeService(LikeMapper likeMapper,
                       UserBehaviorMapper userBehaviorMapper,
                       AsyncUserBehaviorService asyncUserBehaviorService,
                       ContentMapper contentMapper,
                       CommentMapper commentMapper) {
        this.likeMapper = likeMapper;
        this.userBehaviorMapper = userBehaviorMapper;
        this.asyncUserBehaviorService = asyncUserBehaviorService;
        this.contentMapper = contentMapper;
        this.commentMapper = commentMapper;
    }

    /**
     * 点赞切换（自旋）
     * 同步处理点赞记录和统计，异步处理用户行为和画像更新
     *
     * @param userId 用户ID
     * @param targetId 目标ID（内容ID或评论ID）
     * @param targetType 目标类型（CONTENT 或 COMMENT）
     * @return 返回最终的点赞状态：true-已点赞，false-已取消点赞
     */
    @Transactional
    public boolean toggleLike(Long userId, Long targetId, String targetType) {
        try {
            log.debug("开始处理点赞切换，用户ID: {}, 目标ID: {}, 目标类型: {}", userId, targetId, targetType);

            // 1. 验证目标对象是否存在
            validateTargetExists(targetId, targetType);

            // 2. 检查当前点赞状态
            Like existingLike = likeMapper.selectLikeByUserAndTarget(userId, targetId, targetType);

            boolean finalLikeStatus;

            if (existingLike != null) {
                // 当前已点赞，执行取消点赞（同步操作）
                if ("CONTENT".equals(targetType)) {
                    processContentUnlike(userId, targetId);
                } else if ("COMMENT".equals(targetType)) {
                    processCommentUnlike(userId, targetId);
                }
                finalLikeStatus = false;
                log.debug("点赞切换完成：取消点赞，用户ID: {}, 目标ID: {}, 目标类型: {}", userId, targetId, targetType);
            } else {
                // 当前未点赞，执行点赞（同步操作）
                if ("CONTENT".equals(targetType)) {
                    processContentLike(userId, targetId);
                } else if ("COMMENT".equals(targetType)) {
                    processCommentLike(userId, targetId);
                }
                finalLikeStatus = true;
                log.debug("点赞切换完成：点赞，用户ID: {}, 目标ID: {}, 目标类型: {}", userId, targetId, targetType);
            }

            return finalLikeStatus;

        } catch (IllegalArgumentException e) {
            // 参数验证失败，直接抛出原异常，让全局异常处理器处理为400错误
            log.error("点赞切换参数验证失败，用户ID: {}, 目标ID: {}, 目标类型: {}, 错误: {}",
                    userId, targetId, targetType, e.getMessage());
            throw e;
        } catch (Exception e) {
            log.error("处理点赞切换时发生异常，用户ID: {}, 目标ID: {}, 目标类型: {}", userId, targetId, targetType, e);
            throw new RuntimeException("点赞操作失败: " + e.getMessage());
        }
    }

    /**
     * 触发异步用户行为处理
     * 在事务提交后调用，确保异步执行
     *
     * @param userId 用户ID
     * @param targetId 目标ID
     * @param targetType 目标类型
     * @param isLiked 最终点赞状态
     */
    public void triggerAsyncBehaviorProcessing(Long userId, Long targetId, String targetType, boolean isLiked) {
        if ("CONTENT".equals(targetType)) {
            if (isLiked) {
                // 异步处理点赞行为
                asyncUserBehaviorService.processLikeBehaviorAsync(userId, targetId);
            } else {
                // 异步处理取消点赞行为
                asyncUserBehaviorService.processUnlikeBehaviorAsync(userId, targetId);
            }
        }
        // 评论点赞不触发用户画像更新，所以不需要异步处理
    }

    /**
     * 同步处理内容点赞（只处理点赞记录和统计更新）
     */
    private void processContentLike(Long userId, Long contentId) {
        // 1. 插入点赞记录
        int likeInserted = likeMapper.insertLike(userId, contentId, "CONTENT");
        if (likeInserted <= 0) {
            throw new RuntimeException("插入点赞记录失败");
        }

        // 2. 更新内容点赞数
        int updateCount = userBehaviorMapper.updateContentLikeCount(contentId);
        if (updateCount <= 0) {
            log.warn("内容点赞数更新失败，可能内容不存在，内容ID: {}", contentId);
        }

        log.debug("内容点赞同步处理完成，用户ID: {}, 内容ID: {}", userId, contentId);
    }

    /**
     * 同步处理内容取消点赞（只处理点赞记录和统计更新）
     */
    private void processContentUnlike(Long userId, Long contentId) {
        // 1. 删除点赞记录
        int likeDeleted = likeMapper.deleteLike(userId, contentId, "CONTENT");
        if (likeDeleted <= 0) {
            throw new RuntimeException("删除点赞记录失败");
        }

        // 2. 更新内容点赞数（减少）
        int updateCount = userBehaviorMapper.updateContentLikeCountDecrement(contentId);
        if (updateCount <= 0) {
            log.warn("内容点赞数减少失败，可能内容不存在或点赞数已为0，内容ID: {}", contentId);
        }

        log.debug("内容取消点赞同步处理完成，用户ID: {}, 内容ID: {}", userId, contentId);
    }

    /**
     * 同步处理评论点赞（只处理点赞记录和统计更新）
     */
    private void processCommentLike(Long userId, Long commentId) {
        // 1. 插入点赞记录
        int likeInserted = likeMapper.insertLike(userId, commentId, "COMMENT");
        if (likeInserted <= 0) {
            throw new RuntimeException("插入评论点赞记录失败");
        }

        // 2. 更新评论点赞数
        int updateCount = userBehaviorMapper.updateCommentLikeCount(commentId);
        if (updateCount <= 0) {
            log.warn("评论点赞数更新失败，可能评论不存在，评论ID: {}", commentId);
        }

        log.debug("评论点赞同步处理完成，用户ID: {}, 评论ID: {}", userId, commentId);
    }

    /**
     * 同步处理评论取消点赞（只处理点赞记录和统计更新）
     */
    private void processCommentUnlike(Long userId, Long commentId) {
        // 1. 删除点赞记录
        int likeDeleted = likeMapper.deleteLike(userId, commentId, "COMMENT");
        if (likeDeleted <= 0) {
            throw new RuntimeException("删除评论点赞记录失败");
        }

        // 2. 更新评论点赞数（减少）
        int updateCount = userBehaviorMapper.updateCommentLikeCountDecrement(commentId);
        if (updateCount <= 0) {
            log.warn("评论点赞数减少失败，可能评论不存在或点赞数已为0，评论ID: {}", commentId);
        }

        log.debug("评论取消点赞同步处理完成，用户ID: {}, 评论ID: {}", userId, commentId);
    }

    /**
     * 验证目标对象是否存在
     *
     * @param targetId 目标ID
     * @param targetType 目标类型
     */
    private void validateTargetExists(Long targetId, String targetType) {
        if ("CONTENT".equals(targetType)) {
            // 验证内容是否存在且已发布
            var content = contentMapper.selectById(targetId);
            if (content == null) {
                throw new IllegalArgumentException("内容不存在，内容ID: " + targetId);
            }
            if (Boolean.FALSE.equals(content.getIsPublished())) {
                throw new IllegalArgumentException("内容已被删除或未发布，内容ID: " + targetId);
            }
        } else if ("COMMENT".equals(targetType)) {
            // 验证评论是否存在且未删除
            var comment = commentMapper.selectById(targetId);
            if (comment == null) {
                throw new IllegalArgumentException("评论不存在，评论ID: " + targetId);
            }
            if (Boolean.TRUE.equals(comment.getIsDeleted())) {
                throw new IllegalArgumentException("评论已被删除，评论ID: " + targetId);
            }
        }
    }
}